/**********************************************************
 *
 *  Copyright (c) 2003  SeikoEpson Inc
 *  All Rights Reserved
 *
 *  File name : f_sin.c
 *  Function  :
 *        f_asin function returns arcsin's( sin^-1, not 1/sin) value.
 *        This file is copied from math.lib of 
 *                  CC33 tool(CC33v40.exe + CCPA45.exe, 
 *                  math of ansilib33v25 )
 *  original file's Revision  :
 *      2000/02/14    first release                 M.Igarashi
 *  Revision  :
 *      2003/04/01    IrumaSoft M.Takeishi   1.st design
 *
 **********************************************************/
#include	<f_math.h>
#include	<f_smcvals.h>

// ARGORITHM
// 1.let x to be x / sqrt( 1 - x^2 )
// 2.asin(x) = arctan( x / sqrt( 1 - x^2 ) )
//

//
//  the architecture of float floating point
//
//   0 30         23 22                0  32 bit
//   -----------------------------------
//  | |   exponent  |  fraction         |
//   -----------------------------------
//
//  |               |                   |
//  |    8 bits     |    23 bits        |
//
//         bit    31         sign bit        (  1 bit  )
//             30 - 23      exponent part    (  8 bits )
//             22 -  0      fraction part    ( 23 bits )
//
//
//


float f_asin(float sfX){

	long lX;
	unsigned long ulx;
	float	sfTemp;
	float sfX2,sfRet;
	
	
	F_GETW(lX,sfX);		// get low
	F_CLR_SIGN( sfX2, sfX );	// clear sign
	
	ulx = lX&0x7fffffff;

	if( ulx > 0x3f800000 ){		//check area, ulx > 1.0*2^0
		errno = EDOM;
		return( f_NAN._F );
	}
	sfTemp=sfX2*sfX2;
	sfTemp=1.0f-sfTemp;
	sfTemp = f_sqrt(sfTemp);
	
	if(ulx > 0x3f333333 ){	//check area  ulx > 0.7
		sfTemp=sfTemp/sfX2;
		sfTemp=F_HLFP - f_atan(sfTemp);
	}else{
		sfTemp=sfX2/sfTemp;
		sfTemp=f_atan(sfTemp);
	}

	if( (lX&0x80000000) ==0 ){		// positive
		sfRet = sfTemp;
		return sfRet;
	}else{
		sfRet =-sfTemp;				// negative
		return sfRet;
	}

}
